package com.qf.controller;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.qf.pojo.R;
import com.qf.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

//@RestController
//@RequestMapping("/user")
//@DefaultProperties(defaultFallback="default_fb")
public class UserController2 {

    /*
        默认降级方法返回值要和被保护的资源方法保持一致，参数列表留空的
        在参数列表的最后，可选添加一个异常对象，收集异常信息
     */
    public R default_fb(Throwable e){
        e.printStackTrace();
        return R.error().putMsg("default 降级....");
    }

    @Autowired
    UserService userService;

    @Autowired
    private RestTemplate restTemplate;


    @GetMapping("/{id}")

    //标识当前这个资源是被Hystrxi框架保护的一个资源（策略：超时机制、线程池隔离、熔断机制）
    /*
        Hystrix内部默认的超时时间是1s
     */
    @HystrixCommand(commandProperties = {
            //配置hystix服务保护超时机制的超时时间
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000"),
            //触发熔断的请求阈值
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "2"),
            //触发熔断的请求错误比例
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"),
            //触发熔断后的熔断时间
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000")
    },threadPoolProperties = {
            //配置隔离线程池的核心线程数大小（同时控制核心线程数和最大线程数）
            @HystrixProperty(name = "coreSize",value = "5")
    }/*,fallbackMethod = "findOrders_fb"*/)
    public R findOrders(@PathVariable("id") Integer id) throws InterruptedException {

        //发起远程访问，访问order服务
        R r = restTemplate.getForObject("http://QF-ORDER/order/" + id, R.class);

        return r;
    }

    /*
        针对findOrders方法的降级方法
            这个方法的返回值和参数列表需要和目标受保护方法保持一致
            在参数列表的最后，可选添加一个异常对象，用来接收异常信息
     */
    public R findOrders_fb(Integer id,Throwable e){
        e.printStackTrace();
        return R.error().putMsg("服务器忙，稍后重试...");
    }
}
